import wx
from socket import socket,AF_INET,SOCK_STREAM
import threading
import time
'''
基本概念：
在 Python 的 wxPython 库中，wx.Frame 是一个非常重要的类，用于创建应用程序的主窗口或其他独立的窗口。以下是关于 wx.Frame 的详细介绍：
wx.Frame 是一个窗口，其大小和位置通常可以由用户改变。它一般具有粗边框和标题栏，并且可以选择性地包含菜单栏、工具栏和状态栏。
wx.Frame 可以作为容器，包含面板对象、控件对象以及子窗体对象等。
构造函数参数：
parent：当前窗口的父窗口。如果当前窗口是顶级窗口，则 parent=None；如果不是顶层窗口，则它的值为所属 Frame 的父窗口对象。
id：窗体编号。如果设置为 -1，则系统自动分配一个编号。
title：窗体的标题栏文字。
pos：窗体的位置坐标，默认值为 (-1, -1)，表示窗体的位置由系统决定。
size：窗体的大小，默认值为 (-1, -1)，即大小由系统决定。
style：窗体样式，用于控制窗体的外观和行为，例如是否显示标题栏、最大化按钮、最小化按钮等。默认值为 wx.DEFAULT_FRAME_STYLE，它是多种样式的组合2。
name：窗体名称，可通过该名称找到窗体。
常用方法2：
CreateStatusBar(self, number=1, style=STB_DEFAULT_STYLE, id=-1, name=StatusBarNameStr)：在窗体底部创建状态栏。
CreateToolBar(self)：创建工具栏。
SetTitle(self, title)：设置窗体的标题栏内容。
GetTitle(self)：获取窗体的标题。
SetPosition(self, pos)：设置窗口的位置。
GetPosition(self)：获取窗口的位置坐标。
SetSize(self, size)：调整窗口的大小。
GetSize(self)：获取窗口的大小。
Center(self, direction=wx.BOTH)：设置窗体居中，direction 参数可取值 wx.HORIZONTAL（水平居中）、wx.VERTICAL（垂直居中）或 wx.BOTH（水平和垂直同时居中）。
窗体样式2：
wx.DEFAULT_FRAME_STYLE：这是每个窗口的缺省风格，包含标题、可调节大小的边框、最大最小化按钮、关闭按钮和系统菜单等。
wx.CAPTION：在框架上增加一个标题栏。
wx.MINIMIZE_BOX：显示一个最小化按钮。
wx.MAXIMIZE_BOX：显示一个最大化按钮。
wx.RESIZE_BORDER：给框架增加一个可以改变尺寸的边框。
wx.CLOSE_BOX：显示一个关闭按钮。
wx.STAY_ON_TOP：设置为顶层窗体，始终在其他窗口的上面。
wx.FRAME_TOOL_WINDOW：创建的框架看起来像一个工具框窗口，在 Windows 下不会出现在任务栏上。
wx.FRAME_SHAPED：允许创建非矩形的窗口。
'''
'''class mwyClient(wx.Frame):
    def __init__(self,client_name):
        #调用父类的初始化方法，创建一个窗口
        #None：没有父级窗口
        #id表示当前窗口的一个编号
        #pos：窗口的打开位置
        #size：窗体的大小，单位是像素，(宽,高)
        wx.Frame.__init__(self,None,id=1001,title=client_name+'的客户端界面',pos=wx.DefaultPosition,size=(400,500))
        #创建面板对象
        pl=wx.Panel(self)
        #创建盒子并在面板中放上盒子
        box=wx.BoxSizer(wx.VERTICAL)#垂直方向向上自动排版
        #可伸缩的网络布局
        fgz1=wx.FlexGridSizer(wx.HSCROLL)#水平方向可伸缩的布局
        #创建两个按钮
        conn_btn=wx.Button(pl,size=(200,40),label='连接')
        dis_btn=wx.Button(pl,size=(200,40),label='断开')
        #把两个按钮放到可伸缩的网络布局
        fgz1.Add(conn_btn,1,wx.TOP|wx.LEFT)
        fgz1.Add(dis_btn,1,wx.TOP|wx.RIGHT)
        #（可伸缩的网格布局）添加到box中
        box.Add(fgz1,wx.ALIGN_CENTRE)
        #只读文本框，显示聊天内容
        self.show_text=wx.TextCtrl(pl,size=(400,260),style=wx.TE_MULTILINE|wx.TE_READONLY)#wx.TE_MULTILINE表示多行文本框 wx.TE_READONLY表示只读
        box.Add(self.show_text,1,wx.ALIGN_CENTRE)#wx.ALIGN_CENTRE表示self.show_text添加入中间位置
        #创建聊天内容的文本框
        self.chat_text=wx.TextCtrl(pl,size=(400,120),style=wx.TE_MULTILINE)
        box.Add(self.chat_text, 1, wx.ALIGN_CENTRE)
        #创建一个可伸缩的网格布局
        fgz2=wx.FlexGridSizer(wx.HSCROLL)
        reset_btn=wx.Button(pl, size=(200, 40), label='重置')
        send_btn=wx.Button(pl, size=(200, 40), label='发送')
        fgz2.Add(reset_btn,1,wx.TOP|wx.LEFT)
        fgz2.Add(send_btn,1,wx.TOP|wx.LEFT)
        #将fgz2添加进盒子当中
        box.Add(fgz2,1,wx.ALIGN_CENTRE)
        #将盒子放入面板当中
        pl.SetSizer(box)
        #创建的窗口中 高当中有40个像素的间隙

        '''-------------------以上代码是客户端界面的绘制---------------------'''
        self.Bind(wx.EVT_BUTTON,self.connect_to_server,conn_btn)
        #实例属性的设置
        self.client_name=client_name
        self.isconnected=False#存储客户端连接服务器的状态 默认为False 没连
        self.client_socket=None#设置客户端的socket对象为空
        #给发送按钮绑定一个事件
        self.Bind(wx.EVT_BUTTON,self.send_to_server,send_btn)
        #给断开按钮绑定一个事件
        self.Bind(wx.EVT_BUTTON,self.dis_connect_server,dis_btn)
        #给重置按钮绑定一个事件
        self.Bind(wx.EVT_BUTTON,self.reset,reset_btn)
    def reset(self,event):
        self.chat_text.Clear()

    def dis_connect_server(self,event):
        self.client_socket.send('mwy-disconnect'.encode('utf-8'))#发送数据编码 向服务器发送断开连接的信息 服务器调用了 SesstionThread(threading.Thread)和server.show_info_and_send_client('服务器通知',f'{self.user_name}离开聊天室',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))方法
        #False断开连接 不执行connect_to_server(self,event)和send_to_server(self)方法
        self.isconnect=False
    def send_to_server(self,event):
        #判断连接状态
        if self.isconnected:
            input_data=self.chat_text.GetValue()
            if input_data!='':
                #向服务器发送数据
                self.client_socket.send(input_data.encode('utf-8'))#client_socket-->data(SesstionThread)
                #发完数据以后 清空文本框
                self.chat_text.SetValue('')#向文本框复制''字符串
    def connect_to_server(self,event):
        print(f'客户端{self.client_name}连接服务器成功')
        #如果客户端没有连接服务器 则开始连接
        if not self.isconnected:
            #TCP编程的步骤
            server_host_port=('127.0.0.1',8888)
            #创建socket对象
            self.client_socket=socket(AF_INET,SOCK_STREAM)
            #发送连接请求
            self.client_socket.connect(server_host_port)
            #发送信息 user_name=session_socket.recv(1024).decode('utf-8')
            self.client_socket.send(self.client_name.encode('utf-8'))
            #启动一个线程 客户端的线程与服务器的会话线程进行会话
            client_thread=threading.Thread(target=self.recv_data)
            #设置成守护线程 窗体关闭 子线程也结束
            client_thread.daemon=True
            #修改一下连接状态
            self.isconnected=True
            #启动线程
            client_thread.start()
    def recv_data(self):
        while self.isconnected:
            data=self.client_socket.recv(1024).decode('utf-8')
            #显示到只读文本框
            self.show_text.AppendText('-'*40+'\n'+data+'\n')'''
''''''
if __name__=='__main__':
    #初始化App()
    app=wx.App()
    #创建自己的客户端界面对象
    client=mwyClient('python_mwy_client1')#client_name-->python_mwy
    client.Show()#可以改成 mwyClient('python_mwy').Show()

    #循环刷新显示
